package common

import (
	"layim/controllers"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"gopkg.in/kataras/iris.v6"
	"gopkg.in/kataras/iris.v6/middleware/pprof"
	"layim/models"
	"gopkg.in/kataras/iris.v6/middleware/logger"
	"gopkg.in/kataras/iris.v6/middleware/recover"
	"gopkg.in/kataras/iris.v6/adaptors/view"
	"gopkg.in/kataras/iris.v6/adaptors/sessions"
	"time"
	"log"
	"gopkg.in/kataras/iris.v6/adaptors/websocket"
	"gopkg.in/kataras/iris.v6/adaptors/httprouter"
)

var ws websocket.Server
var _gorm *gorm.DB
var app *iris.Framework
//var _cache *cache.Cache
//SetIrisConfig 设置框架整体配置

func init() {
	app = iris.New()
	app.Adapt(
		sessions.New(sessions.Config{
			Cookie:  "gosessionid",
			Expires: 7 * 24 * 3600 * time.Second,
		}),
		httprouter.New(),
		view.Django("views", ".html").Reload(true),
		iris.DevLogger(),
	)

	app.Use(recover.New())
}

func SetIrisConfig() {
	//数据库配置
	app.Config.Other["dbdrver"] = "mysql"
	app.Config.Other["dbserver"] = "tcp(qdm19508111.my3w.com:3306)"
	app.Config.Other["dbport"] = 3306
	app.Config.Other["dbname"] = "qdm19508111_db"
	app.Config.Other["dbuser"] = "qdm19508111"
	app.Config.Other["dbpass"] = "ccb159781"
	app.Config.Other["dbcharset"] = "utf8"
	app.Config.Other["port"] = "2016"
	//iriscontrol
	app.Config.Other["iris_control_port"] = 2018
	app.Config.Other["iris_control_username"] = "backend"
	app.Config.Other["iris_control_password"] = "backend"

	//设置配置模式
	app.Config.Gzip = true             //返回数据异常 需要关闭
	app.Config.CheckForUpdates = false //检查更新
	app.Config.Charset = "UTF-8"       //设置响应内容字符集
	//注册模板信息
}

//GetConfig 获取全局注入配置
func GetConfig(name string) interface{} {
	return app.Config.Other[name]
}

//SetIrisStatic 设置网站静态资源配置
func SetIrisStatic() {
	relmap := map[string]string{
		"font":  "assets/layim/font", //设置字体
		"assets":       "assets", //设置素材静态文件映射
	}
	app.Favicon("./assets/favicons.ico") //设置ICO图标
	for k, v := range relmap {
		app.StaticWeb("/" + k, "./" + v)
	}
}

//RunServer 运行服务器
func RunServer() {
	app.Listen(":" + GetConfig("port").(string))
	//优化关闭服务器
	//graceful.Run(":"+GetConfig("port").(string), time.Duration(10)*time.Second, iris.Default)
}

//GetOrm 全局获取ORM对象
func GetOrm() *gorm.DB {
	if _gorm != nil {
		return _gorm
	}
	//设置默认表前缀
	gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
		return "layim_" + defaultTableName
	}
	driver := GetConfig("dbdrver").(string)
	user := GetConfig("dbuser").(string)
	pass := GetConfig("dbpass").(string)
	dbname := GetConfig("dbname").(string)
	dbserver := GetConfig("dbserver").(string)
	charset := GetConfig("dbcharset").(string)
	dsn := user + ":" + pass + "@" + dbserver + "/" + dbname + "?charset=" + charset
	dsn = dsn + "&parseTime=True&loc=Local"
	orm, err := gorm.Open(driver, dsn)
	orm.SingularTable(true) //防止表名自动添加复数形式
	orm.LogMode(true)       //显示SQL日志
	if err != nil {
		log.Fatal(err.Error())
	}
	_gorm = orm
	return _gorm
}

//SetErrorPage 设置全局错误页面
func SetErrorPage() {
	app.OnError(iris.StatusNotFound, func(this *iris.Context) {
		//404
		if !this.IsAjax() && this.Method() == "GET" {
			this.Render("public.html", map[string]interface{}{"message": "Oh.Page Not Found!"})
		}
	})
	app.OnError(iris.StatusInternalServerError, func(this *iris.Context) {
		//500
		if ! this.IsAjax() && this.Method() == "GET" {
			this.Render("public.html", map[string]interface{}{"message": "Oh.Server Error!"})
		}
	})
}

//Middleware 注册全局中间件
func Middleware() {
	app.Get("/pprof/*action", pprof.New()) //性能监控
	app.Use(logger.New())                  //日志显示
}

//SetWebSocket 设置socket监听路径服务器
func SetWebSocket(path string) {
	ws = websocket.New(websocket.Config{}) // 获取websocket服务
	ws.OnConnection(func(c websocket.Connection) {
		chatController := controllers.ChatController{Orm: GetOrm(), WsCon: c}
		c.OnMessage(func(data []byte) {
			chatController.SocketOnMessage(data)
		})
		c.OnDisconnect(func() {
			chatController.SocketDisconnect()
		})
	})
	app.Any(path, ws.Handler())        //向路由内注册一个Ws服务
}

//初始化启动服务器时候清除所有
func InitClearUserWsId() {
	orm := GetOrm()
	if orm.Model(&models.User{}).Where("1=1").Update(map[string]interface{}{"wsid": ""}).RowsAffected > 0 {
		log.Println("All User WsId Is Update")
	}
}
